package cn.sisyphe.framework.common.stopwatch;


import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import org.springframework.util.StringUtils;

/**
 * Created by heyong on 2017/10/17 9:23
 * Description: 此监控主要用于问题排查，生产环境慎用
 *
 * @author heyong
 */
@Aspect
@Component
public class StopWatchTimeAdvice {

    @Pointcut("execution(* cn.sisyphe.framework.common.stopwatch.StopWatchStep.watch(..))")
    public void step() {
    }


    private StopWatch stopWatch;

    @Around("@annotation(stopWatchTime)")
    public Object invoke(ProceedingJoinPoint thisJoinPoint, StopWatchTime stopWatchTime) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
        String name = StringUtils.isEmpty(stopWatchTime.value()) ? methodSignature.getName() : stopWatchTime.value();

        stopWatch = new StopWatch(name);
        if (!stopWatch.isRunning()) {
            stopWatch.start("00");
        }

        Object object = thisJoinPoint.proceed();

        if (stopWatch.isRunning()) {
            stopWatch.stop();
        }

        System.err.println(stopWatch.prettyPrint());

        return object;
    }


    @Around("step()")
    public Object invokeWithStep(ProceedingJoinPoint thisJoinPoint) throws Throwable {

        if (stopWatch == null) {
            stopWatch = new StopWatch();
        }

        Object[] args = thisJoinPoint.getArgs();
        for (Object object : args) {
            if (stopWatch.isRunning()) {
                stopWatch.stop();
            }

            if (!stopWatch.isRunning()) {
                stopWatch.start(object.toString());
            }
        }


        return null;
    }


}
